/*
 * Team Huskies:
 * Aakanksha Gaur,
 * Alice Robinson,
 * Paul Winters,
 * Steve Bradshaw
 * Date: June 8th 2011
 */

#ifndef PROCESS_H
#define PROCESS_H


typedef struct process_str {
	int	no_steps;		// number of time steps before resetting to 0 - number of instructions
	int no_requests;	// number of requests that will be generated during the process run
	int * requests;		// an array of requests, each request (e.g. io service) is issued at a specific
	int id;				// time step. These are the synchronous events that result in traps being issued.
						// You can get fancy and make this an array of RequestTypeStr which contains the
						// step number when issued, and a request type (e.g. 0=io, 1=sync, etc.)
	//int ** the_requests; //the step that generates the request
	int (*array)[2];
} ProcessStr;

typedef struct pcb_str {
	int	pid;
	int next_step;		// this is the step count that the CPU had gotten to when this process was
						// prempted (like a PC register value)
	int state;			// e.g. 0=running, 1=ready, 2=interrupted, 3=blocked
	int waiting_on;		// which queue is it in if it is waiting on something (blocked)
	int owns;			// which semaphore does it own
	//int (*the_requests_placement)[2]; //the step that generates the request
	int requests_size;
	ProcessStr *my_process;
	int request_no;
	// anything else you need
} PCB_str;

/*
 * Creates the process.  The id is used to then create the associated PCB.
 * @return a new PCB which is associated to this process by ID.
 */
PCB_str create_p(int the_steps, int the_id, char the_process_type);

/*
 * create the associated Process Contol Block for this process.
 */
PCB_str create_pcb(int the_id, int the_requests, ProcessStr *process);

//int** get_request_list(PCB_str *pcb); Won't work

/*
 * Used to do a context most context switches.  For semi's the setter will
 * to be used in addition.
 */
void update_pcb(PCB_str *pcb, int next_step, int state, int queue_id);

/*
 * Sets the next step.
 */
void set_next_step(PCB_str *pcb, int the_next_step);

/*
 * Get the next step to start execution.
 * @return is an integer value to start execution.
 */
int get_next_step(PCB_str *pcb) ;

/*
 * Set the state. 0=running, 1=ready, 2=interrupted, 3=blocked.
 */
void set_state(PCB_str *pcb, int the_state);

/*
 * Get the state.
 * @return an integer state. 0=running, 1=ready, 2=interrupted, 3=blocked
 */
int get_state(PCB_str *pcb) ;

/*
 * Set the queue_id that is blocking this process. int 1 = ready.
 */
void set_waiting_on(PCB_str *pcb, int queue_id) ;

/**
 * Query which queue id the process is in.
 * @return an integer with queue id.
 */
int get_waiting_on(PCB_str *pcb);

/*
 * Setter for the semiphore it owns
 */
void set_sem_id(PCB_str *pcb, int the_sem_id);

/*
 * Getter for which semiphore this process owns
 */
int get_sem_id(PCB_str *pcb);

#endif /* PROCESS_H */


